/* Name: 	Rio Atmadja
   Program:	stack_array.h
*/
#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <fstream>

/*-------------------------------------------------------*/
/*  *stack_array(int stack_size) --> this is the de-     */
/*  fault constructor for this class		         */
/*  int stack_size --> set the size of the stack         */
/*  postcondition  --> the stack is empty 		 */
/*-------------------------------------------------------*/
template <class Type>
stack_array<Type>::stack_array() {

	size = 1000; //set the size of the array
	position = 0; //set the position to zero
	current = 0; //set the length to zero
	list = new Type[size]; //create the array to hold the stack elements
}

/*-------------------------------------------------------*/
/*  *~stack_array() --> this is the default destractor   */
/*-------------------------------------------------------*/
template <class Type>
stack_array<Type>::~stack_array() {

	delete [] list; //delete the list
}

/*-------------------------------------------------------*/
/*  *push(Type data) --> this function push an element   */
/*  into the stack		   			 */
/*   Type data -> data to be inserted into the stack	 */
/*-------------------------------------------------------*/
template <class Type>
void stack_array<Type>::push(Type data) {
	
	list[position] = data; //insert the data
	position++;//increment the counter	
	current++;
}

/*-------------------------------------------------------*/
/*  *top() --> return the top element of the list 	 */
/*-------------------------------------------------------*/
template <class Type>
Type stack_array<Type>::top() {

	if( !isFull() ) {

		return list[position-1];

	} else {

		cout << " nothing to be returned " << endl;
	}

}

/*-------------------------------------------------------*/
/*  *getIndex() --> return the ith element of the list 	 */
/*-------------------------------------------------------*/
template <class Type>
Type stack_array<Type>::getIndex(int i) {

	if( i < position) {

		return list[i];

	} else {

		cout << " nothing to be returned " << endl;
	}

}

/*--------------------------------------------------------*/
/*  *pop() --> delete an element in the stack from  the   */
/*  the back [ LIFO style] 				  */
/*--------------------------------------------------------*/
template <class Type>
void stack_array<Type>::pop() {

	if(!isEmpty()) {	
		position--;//decrement the position of the counter 
		current--;
   	}
}

/*---------------------------------------------------------*/
/*   *isEmpty() --> this function check if the stack is    */
/*    empty or not 					   */
/*---------------------------------------------------------*/
template <class Type>
bool stack_array<Type>::isEmpty() const {
	
	return ( position == 0);
}

/*---------------------------------------------------------*/
/*   *isFull() --> this function check if the stack is     */
/*    full						   */
/*---------------------------------------------------------*/
template <class Type>
bool stack_array<Type>::isFull() {
	
	return ( position == size );
}

/*---------------------------------------------------------*/
/*  *length() --> return the length of the stack	   */
/*---------------------------------------------------------*/
template <class Type> 
int stack_array<Type>::length() {
	
	return current;
}

/*----------------------------------------------------------*/
/*  *print() --> print the stack to the console		    */
/*----------------------------------------------------------*/
template <class Type> 
void stack_array<Type>::print() {
	
	cout << "[";
	for(int i=0; i<length(); i++) {
		cout << list[i] << " ";
	}
	cout << "]" << endl;	
}

/*-----------------------------------------------------------*/
/*  *shuffle(Type data) --> shuffle the data elements 	     */
/*-----------------------------------------------------------*/
template <class Type>
void stack_array<Type>::shuffle() {
	
	for( int i=0; i<length(); i++) {
	
		int random = 1 + (rand() % length() - 1);
		Type temp = list[i];
		list [i] = list[random];
		list[random] = temp;		
	}
}

/*------------------------------------------------------------*/
/*  *print-to-file()   -->  print output to a file	      */
/*------------------------------------------------------------*/
template <class Type> 
void stack_array<Type>::print_to_file() {

	ofstream file("output.txt");
	if( file.good() ) {
	
		for(int i=0; i<length(); i++) {
			file  << list[i] << " "; //write to the file
		}
		file << endl; 
		file.close(); //close the file

	} else {
	
		cout << "ERROR: cannot open file for writing " << endl;	
	}

}

/*-------------------------------------------------------------*/
/* *read_file()  --> this function read data from a file       */
/*-------------------------------------------------------------*/
template <class Type>
bool stack_array<Type>::read_file() {

	int position = 0; //keep track of the posisiton
	ifstream file("output.txt"); //open the file

	if (!file) {

		cerr << "File could not be opened." << endl;
		return false;
	
	} else {
	
		while( !file.eof() ) {

			file >> list[position]; 
			cout << list[position] << " ";
			position++; //increment the position
		}
		cout << endl;
	}

	file.close();
	return true;
}
